package com.gesonet.pay.utils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PayCommonUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(PayCommonUtil.class);
	
	public static final String CHAR_ENCODING = "UTF-8";
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
	/**
	 * 生成商户系统内部的订单号
	 * @return
	 */
	public static String createTradeOrderNo(int length) {
		//自定义订单号，此处仅作举例
		return sdf.format(new Date()) + createNoncestr(length);
	}
	/**
	 * 随机字符串，不长于 32位
	 * @return
	 */
	public static String createNonceStr() {
		String currTime = getCurrTime();
		//8位日期
		String strTime = currTime.substring(8, currTime.length());
		//四位随机数
		String strRandom = buildRandom(4) + "";
		//10位序列号,可以自行调整。
		String strReq = strTime + strRandom;
		return strReq;
	}
	
	/**
	 * 取出一个指定长度大小的随机正整数.
	 * @param length int 设定所取出随机数的长度。length小于11
	 * @return int 返回生成的随机数。
	 */
	private static int buildRandom(int length) {
		int num = 1;
		double random = Math.random();
		if (random < 0.1) {
			random = random + 0.1;
		}
		for (int i = 0; i < length; i++) {
			num = num * 10;
		}
		return (int) ((random * num));
	}
	
	/**
	 * 获取当前时间 yyyyMMddHHmmss
	 * @return String
	 */ 
	private static String getCurrTime() {
		Date now = new Date();
		SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		String s = outFormat.format(now);
		return s;
	}
	
	public static String createNoncestr(int length) {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < length; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}
	

	/**
	 * @date 2014-12-5下午2:29:34
	 * @Description：sign签名
	 * @param characterEncoding 编码格式
	 * @param parameters 请求参数
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String createMapMD5Sign(SortedMap<String, String> parameters,String extraStr) {
		StringBuffer sb = new StringBuffer();
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			if (StringUtils.isNotBlank(v)) {
				sb.append(k + "=" + v + "&");
			}
		}
		String encodeStr = sb.toString();
		if(StringUtils.isNotBlank(extraStr)){
			sb.append(extraStr);
			encodeStr = sb.toString();
		}else{
			encodeStr = encodeStr.substring(0, encodeStr.lastIndexOf("&"));
		}
		
		logger.debug("md5 加密的字符串为:{}",encodeStr);
		return MD5Util.MD5Encode(encodeStr, CHAR_ENCODING).toUpperCase();
	}
	
	
	/**
	 * 对象属性字典序后MD5签名
	 * @param obj 对象
	 * @param extraStr 额外追加的字符串
	 * @return MD5加密串
	 */
	public static String createObjMD5Sign(Object obj,String extraStr){
		String result = "";
		if(obj != null){
			Field[] fields = obj.getClass().getDeclaredFields();
			SortedMap<String,String> sortedMap = new TreeMap<String, String>();
			for (Field field : fields) {
				String fieldName = field.getName();
				if(!ObjectUtils.isStaticField(field)){
					field.setAccessible(true);
					try {
						Object value = field.get(obj);
						if(value != null && StringUtils.isNotBlank(String.valueOf(value))){
							StringBuffer sb = new StringBuffer();
							sb.append("&");
							sb.append(fieldName);
							sb.append("=");
							sb.append(value);
							sortedMap.put(fieldName, sb.toString());
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			Collection<String> values = sortedMap.values();
			StringBuffer sb = new StringBuffer();
			for (String value : values) {
				sb.append(value);
			}
			if(StringUtils.isNotBlank(extraStr)){
				sb.append("&");
				sb.append(extraStr);
			}
			result = sb.toString().replaceFirst("&", "");
			logger.debug("对象属性签名字符串为:{}",result);
			if(StringUtils.isNotBlank(result)){
				return MD5Util.MD5Encode(result, CHAR_ENCODING).toUpperCase();
			}
		}
		return result;
	}
	
	/**
	 * @Title: createTimestamp 
	 * @Description: 从 1970 年 1 月 1 日00：00：00至今的秒数， 即当前的时间，且最终需要 转换为字符串形式
	 * @return: String 
	 * @throws
	 */
	public static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

	/**
	 * @date 2014-12-3上午10:17:43
	 * @Description：返回给微信的参数
	 * @param return_code 返回编码
	 * @param return_msg  返回信息
	 * @return
	 */
	public static String setXML(String return_code, String return_msg) {
		return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg
				+ "]]></return_msg></xml>";
	}
	
}
